package page

import (
	"encoding/binary"
	"ibdreader/slice"
)

type RecordHeader struct {

	/**
	 * fo Flags: A 4-bit bitmap to store boolean flags about this record.
	 * Currently only two flags are defined: min_rec (1) meaning this record is the minimum
	 * record in a non-leaf level of the B+Tree, and deleted (2) meaning the record is
	 * delete-marked (and will be actually deleted by a purge operation in the future).
	 */
	InfoFlag RecordInfoFlag

	/**
	 * Number of Records Owned: The number of records “owned” by the current record in
	 * the page directory. This field will be further discussed in a future post about
	 * the page directory.
	 */
	NumOfRecOwned int64

	/**
	 * Order: The order in which this record was inserted into the heap. Heap records
	 * (which include infimum and supremum) are numbered from 0. Infimum is always order 0,
	 * supremum is always order 1. User records inserted will be numbered from 2.
	 */
	Order int64

	/**
	 * The type of the record, where currently only 4 values are supported:
	 * conventional (0), node pointer (1), infimum (2), and supremum (3).
	 */
	RecordType RecordType

	/**
	 * Next Record Offset: A relative offset from the current record to the origin of the
	 * next record within the page in ascending order by key.
	 * <p>
	 * 直接定位到下一个record的数据部分，而不是header.
	 */
	NextRecOffset int64
}

func RecordHeaderReadSlice() RecordHeader {
	var rh RecordHeader
	b1 := slice.ReadByte()
	rh.InfoFlag = RecordInfoFlagFind(int64(binary.BigEndian.Uint64([]byte{(b1 & 0xf0) >> 4})))
	rh.NumOfRecOwned = int64(binary.BigEndian.Uint64([]byte{b1 & 0x0f}))
	b2 := slice.ReadUnsignedShort()
	rh.RecordType = RecordTypeFind(b2 & 0x07)
	rh.Order = (b2 & 0xfff8) >> 3
	rh.NextRecOffset = slice.ReadShortInt16()
	return rh
}

func RecordInfoFlagFind(flag int64) RecordInfoFlag {
	var rf RecordInfoFlag
	if flag == MIN_REC {
		rf = "MIN_REC"
	} else if flag == DELETE_MARKED {
		rf = "DELETE_MARKED"
	}
	return rf
}

func RecordTypeFind(rtype int64) RecordType {
	var rd RecordType
	if rtype == CONVENTIONAL {
		rd = "CONVENTIONAL"
	} else if rtype == NODE_POINTER {
		rd = "NODE_POINTER"
	} else if rtype == INFIMUM {
		rd = "INFIMUM"
	} else if rtype == SUPREMUM {
		rd = "SUPREMUM"
	} else {
		rd = ""
	}
	return rd
}
